package hehe.worker.base;

import hehe.worker.pool.WorkerPool;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

/**
 * worker 线程
 *<B>说明：</B>
 *<pre>
 * 一个worker 对应一个线程类
 *</pre>
 *<B>示例：</B>
 *<pre>
 *  略
 *</pre>
 *<B>日志：</B>
 *<pre>
 *  略
 *</pre>
 *<B>注意事项：</B>
 *<pre>
 *  略
 *</pre>
 */
public class Worker implements Runnable
{

    /**
     * worker pool
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     */
    WorkerPool workerPool;

    /**
     * 第一个任务
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     */
    protected Runnable firstTask;

    /**
     * 空闲状态
     *<B>说明：</B>
     *<pre>
     * 无任务
     *</pre>
     */
    public static final int FREE_STATUS = 0;

    /**
     * 执行任务中
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     */
    public static final int RUNNING_STATUS = 1;

    /**
     * 选中状态
     *<B>说明：</B>
     *<pre>
     * 说明worker 被选中
     *</pre>
     */
    public static final int SELECTED_STATUS = 2;


    /**
     * worker 状态
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     */
    private int status;

    /**
     * 是否默认worker
     *<B>说明：</B>
     *<pre>
     * 默认worker 不删除
     *</pre>
     */
    private boolean defaultWorker = false;

    /**
     * 完成的任务数量
     *<B>说明：</B>
     *<pre>
     *　略
     *</pre>
     */
    volatile long completedTasks;

    /**
     * 信号量锁
     *<B>说明：</B>
     *<pre>
     * 属性详细描述
     *</pre>
     */
    Semaphore semaphore = new Semaphore(1);

    /**
     * 任务队列
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    private Queue<Runnable> taskQueue;

    /**
     * worker对应的线程
     *<B>说明：</B>
     *<pre>
     *  md 一个线程只能调用一次start 方法
     *  start 结束后,线程结束,回收资源
     *</pre>
     */
    private Thread thread;

    public Worker(Queue taskQueue)
    {
        this(taskQueue,false);
    }

    public Worker(Queue taskQueue,boolean defaultWorker)
    {
        this.taskQueue = taskQueue;
        this.defaultWorker = defaultWorker;
        this.init();
    }

    public Worker()
    {
        this.init();
    }

    private void init()
    {
        this.thread = this.newThread(this);
    }

    public void setWorkerPool(WorkerPool workerPool)
    {
        this.workerPool = workerPool;
    }

    public void setStatus(int status)
    {
        this.status = status;
    }

    public int getStatus()
    {
        return this.status;
    }

    public boolean isDefaultWorker()
    {
        return this.defaultWorker;
    }

    /**
     * worker 运行入口
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    public void start()
    {
        this.start(null);
    }

    /**
     * worker 运行入口
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    public void start(Runnable task)
    {
        // 创建新线程
        this.thread = this.newThread(this);

        this.firstTask = task;
        // 启动线程
        this.thread.start();
    }

    /**
     * 线程运行入口
     *<B>说明：</B>
     *<pre>
     *
     *</pre>
     */
    public void run()
    {
        this.runWorker();
    }

    private void runWorker()
    {
        Runnable task = this.firstTask;
        this.firstTask = null;
        // 加锁失败,直接退出
        if (!this.tryLock()) {
            return;
        }

        this.setStatus(RUNNING_STATUS);

        try {
            while (task != null || (task = this.getNextTask()) != null) {
                // 有任务,加个锁
                Throwable thrown = null;
                try {
                    // 执行任务
                    task.run();
                } catch (RuntimeException ex) {
                    thrown = ex; throw ex;
                } catch (Error ex) {
                    thrown = ex; throw ex;
                } catch (Throwable ex) {
                    thrown = ex; throw new Error(ex);
                } finally {
                    completedTasks++;
                    task = null;

                }
            }
        } finally {
            this.exit();
        }
    }

    /**
     * worker 退出
     *<B>说明：</B>
     *<pre>
     *　应该无任务任务
     *</pre>
     */
    protected void exit()
    {
        // 更新worker 无空闲状态
        this.unlock();
        this.setStatus(RUNNING_STATUS);
        this.workerPool.workerExitEvent(this);
    }

    /**
     * 创建新线程
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    private Thread newThread(Runnable t)
    {
        return Executors.defaultThreadFactory().newThread(t);
    }

    /**
     * 加锁
     *<B>说明：</B>
     *<pre>
     *　略
     *</pre>
     */
    public void lock()
    {
        try {
            this.semaphore.acquire(1);
        } catch (InterruptedException ex) {

        }
    }

    /**
     * 尝试加锁
     *<B>说明：</B>
     *<pre>
     *　如果加锁不成功,返回false
     *</pre>
     */
    public boolean tryLock()
    {
        return this.semaphore.tryAcquire(1);
    }

    /**
     * 释放锁
     *<B>说明：</B>
     *<pre>
     *　略
     *</pre>
     */
    public void unlock()
    {
        this.semaphore.release(1);
    }

    /**
     * 获取下一个任务
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     */
    private Runnable getNextTask()
    {
        if (this.taskQueue.isEmpty()) {
            return null;
        }

        return this.taskQueue.pop();
    }
}
